export const metadata = {
  description: "Get started building a simple server worker with Jazz in 10 minutes."
};

import { Alert, CodeGroup, ContentByFramework, FileName, ReactLogo, SvelteLogo, TabbedCodeGroup, TabbedCodeGroupItem, TextLink } from "@/components/forMdx";
import GetAPIKey from "@/components/docs/snippets/GetAPIKey.mdx";
import InstallJazz from "@/components/docs/snippets/InstallJazz.mdx";
import RunDevServer from "@/components/docs/snippets/RunDevServer.mdx";
import StuckCTA from "@/components/docs/snippets/StuckCTA.mdx";

# Get started with Server Workers in 10 minutes
This quickstart guide will take you from an empty project to a server worker which can interact with your Jazz application.

- You'll get the most out of this guide if you complete [the frontend quickstart guide](/docs/quickstart) first.
- If you've already completed the frontend quickstart, you can skip straight to [extending your schema](#define-your-schema).

<ContentByFramework framework="react">
  ## Create your Next.js App
  We'll be using Next.js for simplicity, but you can use any framework you like.

  You can accept the defaults for all the questions, or customise the project as you like.

  <TabbedCodeGroup id="create-nextjs-app" default="pnpm" savedPreferenceKey="package-manager">
  <TabbedCodeGroupItem label="npm">
  ```sh
  npx create-next-app@latest --typescript jazzfest
  cd jazzfest
  ```
  </TabbedCodeGroupItem>
  <TabbedCodeGroupItem label="pnpm">
  ```sh
  pnpx create-next-app@latest --typescript jazzfest
  cd jazzfest
  ```
  </TabbedCodeGroupItem>
  </TabbedCodeGroup>

</ContentByFramework>
<ContentByFramework framework="svelte">
  ## Create your SvelteKit App
  We'll be using SvelteKit for simplicity, but you can use any framework you like.

  You can accept the defaults for all the questions, or customise the project as you like.

  <TabbedCodeGroup id="create-sveltekit-app" default="pnpm" savedPreferenceKey="package-manager">
  <TabbedCodeGroupItem label="npm">
  ```sh
  npx sv create --types ts --template minimal jazzfest
  cd jazzfest
  ```
  </TabbedCodeGroupItem>
  <TabbedCodeGroupItem label="pnpm">
  ```sh
  pnpx sv create --types ts --template minimal jazzfest
  cd jazzfest
  ```
  </TabbedCodeGroupItem>
  </TabbedCodeGroup>
</ContentByFramework>

<Alert variant="info" className="mt-4 flex gap-2 items-center">
  Requires Node.js 20+
</Alert>

## Install Jazz

The `jazz-tools` package includes everything you're going to need to build your first Jazz server worker.

<InstallJazz />

## Set your API key

<GetAPIKey />

## Define your schema
We're going to define a simple schema for our server worker. We'll use the `root` on the worker to store a list of bands. We're also going to add a migration to initialise the `root` if it doesn't exist.

<ContentByFramework framework="react" savedPreferenceKey="framework">
<FileName>app/schema.ts</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte" savedPreferenceKey="framework">
<FileName>src/lib/schema.ts</FileName>
</ContentByFramework>

<CodeGroup>
```ts schema.ts
```
</CodeGroup>

<Alert variant="info" className="mt-4 flex gap-2 items-center">
  If you're continuing from the [front-end Quickstart](/docs/quickstart), you can extend your existing schema.
</Alert>

## Create a Server Worker

Jazz provides a CLI to create server workers. You can create a server worker using the following command:

<TabbedCodeGroup id="create-worker-account" default="pnpm" savedPreferenceKey="package-manager">
<TabbedCodeGroupItem label="npm">
```sh
npx jazz-run account create --name "JazzFest Server Worker"
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="pnpm">
```sh
pnpx jazz-run account create --name "JazzFest Server Worker"
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

You can copy the output of this command and paste it directly into your `.env` file:

<FileName>.env</FileName>
<TabbedCodeGroup id="worker-env-vars" default="react" savedPreferenceKey="framework">
<TabbedCodeGroupItem label="Next.js" icon={<ReactLogo />} value="react" preferWrap>
```bash
NEXT_PUBLIC_JAZZ_API_KEY=you@example.com # or your API key
#[!code ++:2]
NEXT_PUBLIC_JAZZ_WORKER_ACCOUNT=co_z...
JAZZ_WORKER_SECRET=sealerSecret_z.../signerSecret_z...
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="SvelteKit" icon={<SvelteLogo />} value="svelte" preferWrap>
```bash
PUBLIC_JAZZ_API_KEY=you@example.com # or your API key
#[!code ++:2]
PUBLIC_JAZZ_WORKER_ACCOUNT=co_z...
JAZZ_WORKER_SECRET=sealerSecret_z.../signerSecret_z...
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>
<Alert variant="warning" className="mt-4 flex gap-2 items-center">
  Your `JAZZ_WORKER_SECRET` should **never** be exposed to the client.
</Alert>

## Defining your HTTP request schema

Next, we're going to set up an HTTP request schema to define our request and response. Here, we tell Jazz that we will send a `Band` under the key `band` and expect a `bandList` in response, which is a list of `Band`s.

We also need to tell Jazz which keys should be treated as loaded in the request and response using the `resolve` query.
<ContentByFramework framework="react" savedPreferenceKey="framework">
<FileName>app/announceBandSchema.ts</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte" savedPreferenceKey="framework">
<FileName>src/lib/announceBandSchema.ts</FileName>
</ContentByFramework>
<TabbedCodeGroup id="request-schema" default="react" savedPreferenceKey="framework">
<TabbedCodeGroupItem label="Next.js" icon={<ReactLogo />} value="react" preferWrap>
```ts announceBandSchema.ts
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="SvelteKit" icon={<SvelteLogo />} value="svelte" preferWrap>
```ts announceBandSchema.svelte.ts
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

## Configure your Server Worker

We're going to use the `startWorker` function to start our server worker, and register a `POST` handler, which will listen for the requests being sent to our server worker.

We'll also use a `resolve` query here to make sure that the `bandList` is loaded on the worker's root.

<ContentByFramework framework="react" savedPreferenceKey="framework">
<FileName>app/api/announce-band/route.ts</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte" savedPreferenceKey="framework">
<FileName>src/routes/api/announce-band/+server.ts</FileName>
</ContentByFramework>
<TabbedCodeGroup id="worker-config" default="react" savedPreferenceKey="framework">
<TabbedCodeGroupItem label="Next.js" icon={<ReactLogo />} value="react" preferWrap>
```ts route.ts
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="SvelteKit" icon={<SvelteLogo />} value="svelte" preferWrap>
```ts +server.ts
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

## Start your server worker

We can now start our development server to make sure everything is working.

<RunDevServer />

<ContentByFramework framework="react">
If you open your browser, you should see the default Next.js welcome page.
</ContentByFramework>
<ContentByFramework framework="svelte">
If you open your browser, you should see the default SvelteKit welcome page.
</ContentByFramework>

### Not working?
<ContentByFramework framework="react">
- Check you set up your `.env` file correctly with `NEXT_PUBLIC_` where necessary
</ContentByFramework>
<ContentByFramework framework="svelte">
- Check you set up your `.env` file correctly with `PUBLIC_` where necessary
</ContentByFramework>
- Check you're importing `startWorker` from `jazz-tools/worker`

<StuckCTA />

## Send requests to your server worker

### Creating a Jazz Client
*If you already have a working provider from the frontend quickstart, you can skip this step.*

<ContentByFramework framework="react">
We're going to wrap our Next.js app in a `JazzReactProvider` so that we can use Jazz on our client.
</ContentByFramework>
<ContentByFramework framework="svelte">
We're going to wrap our SvelteKit app in a `JazzSvelteProvider` so that we can use Jazz on our client.
</ContentByFramework>

<ContentByFramework framework="react">
  <FileName>app/layout.tsx</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte">
  <FileName>src/routes/+layout.svelte</FileName>
</ContentByFramework>

<TabbedCodeGroup id="add-provider" savedPreferenceKey="framework">
<TabbedCodeGroupItem label="Next.js" value="react" icon={<ReactLogo />} preferWrap>
  ```tsx layout.tsx
  ```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="Svelte" value="svelte" icon={<SvelteLogo />} preferWrap>
```svelte +layout.svelte
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

### Creating your page component

We're going to send a request to our server worker to announce a new band. Our worker will respond with a list of bands that we can display on our page.

<ContentByFramework framework="react">
<FileName>app/page.tsx</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte">
<FileName>src/routes/+page.svelte</FileName>
</ContentByFramework>

<TabbedCodeGroup id="page-component" default="react" savedPreferenceKey="framework">
<TabbedCodeGroupItem label="Next.js" value="react" icon={<ReactLogo />} preferWrap>
```tsx page.tsx
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="Svelte" value="svelte" icon={<SvelteLogo />} preferWrap>
```svelte +page.svelte
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

## Try it out!
Your browser should now be showing you a page with an input field and a button. If you enter a band name and click the button, your server worker will receive the request and add the band to the list.

**Congratulations! 🎉** You've just built your first Jazz server worker!

This simple pattern is the foundation for building powerful, real-time applications.

Here are some ideas about what you could use your server worker for:

- integrating with payment providers
- sending emails/SMSes
- gathering data from external APIs
- managing authoritative state

Looking forward to seeing what you build!

## Next steps
- Complete the [front-end quickstart](/docs/quickstart) to learn more about how to build real-time UIs using Jazz
- Find out how to [handle errors](/docs/server-side/communicating-with-workers/http-requests#error-handling) gracefully in your server worker
- Learn how to share and [collaborate on data](/docs/permissions-and-sharing/overview) in groups with complex permissions
